<script setup lang="ts">
import type { TreeSelectOption } from 'naive-ui'
import { flatMap } from 'lodash-es'
defineOptions({
  name: 'AuthItem',
})
type Props = {
  options: TreeSelectOption[]
}
const props = withDefaults(defineProps<Props>(), {
  options: () => [],
})

const ids = defineModel<string[]>({
  required: true,
  default: () => [],
})

// 获取所有叶子节点的 ID
const getLastIds = (el: TreeSelectOption) => {
  return el.children?.length ? flatMap(el.children, getLastIds) : [el.id]
}
/**
 * 优化版本：使用父指针映射实现（适合多次查询）
 * @param tree 树形结构数组
 * @param targetId 目标节点 ID
 * @returns 从根节点到目标节点的 ID 数组
 */
const findAllParentIdsOptimized = (tree: TreeSelectOption[], targetId: string): string[] => {
  const parentMap = new Map()
  let targetNode: TreeSelectOption | undefined

  // 构建父指针映射的递归函数
  const buildParentMap = (nodes: TreeSelectOption[], parent?: TreeSelectOption) => {
    nodes.forEach((node) => {
      if (parent) parentMap.set(node.id, parent.id)
      if (node.id === targetId) targetNode = node
      if (node.children) buildParentMap(node.children, node)
    })
  }

  buildParentMap(tree)
  if (!targetNode) return []

  // 从目标节点回溯到根节点
  const path = [targetId]
  let currentId = targetId
  while (parentMap.has(currentId)) {
    currentId = parentMap.get(currentId)!
    path.unshift(currentId)
  }

  return path
}

const childerIds = computed(() => {
  return flatMap(props.options, (el) => getLastIds(el))
})

const checkIds = computed({
  get() {
    return ids.value.filter((id) => childerIds.value.includes(id))
  },
  set(val: string[]) {
    // 收集所有选中的 ID 及其上级 ID
    const allIds = new Set<string>()
    val.forEach((id) => {
      // 查找节点
      findAllParentIdsOptimized(props.options, id).forEach((parentId) => {
        allIds.add(parentId)
      })
    })
    ids.value = Array.from(allIds)
  },
})
</script>

<template>
  <n-tree
    v-model:checked-keys="checkIds"
    show-line
    default-expand-all
    cascade
    checkable
    selectable
    :data="options"
    check-strategy="child"
    label-field="name"
    key-field="id"
    children-field="children"
  />
</template>

<style scoped lang="scss"></style>
